//
//  AiChatExt.swift
//  imprint
//
//  Created by 小柠檬🍋 on 2025/2/7.
//

import Foundation
class AiChatExt {
    
    /**
     * 称呼
     */
    static func getName2(_ aiRole: AiRoleBean) -> String {
        if (aiRole.name2 ?? "").isEmpty {
            var name = userManager.getName()
            if name.isEmpty {
                name = ""
            }
            return name
        } else {
            return aiRole.name2 ?? ""
        }
    }
    
    /**
     * 称呼
     */
    static func getName2(_ aiRole: RoleBean) -> String {
        if (aiRole.name2 ?? "").isEmpty {
            var name = userManager.getName()
            if name.isEmpty {
                name = ""
            }
            return name
        } else {
            return aiRole.name2 ?? ""
        }
    }
    
    //返回hexString 跟。Data格式
    static func doAiVoiceTest(text: String?, voiceId: String?, voiceHex: String?)  async throws -> (String?, Data?) {
        var hexString : String? = nil
        if ((voiceHex ?? "").isEmpty) {
            //下载资源
            hexString =  try await doAiVoiceHexString(text: text, voiceId: voiceId) ?? ""
        } else {
            hexString = voiceHex
        }
        try check(!(hexString ?? "").isEmpty) {
            "下载失败"
        }
        //转换为Data
        return (hexString, hexStringToData(hexString))
    }
    
    //接口请求获取语音hex文本
    static func doAiVoiceHexString(text: String?, voiceId: String? = nil, isSystem: Bool = false) async throws -> String? {
        let voiceText = EmojiUtils.deleteNoEmotionContentAll(text)
        if let voiceText = voiceText{
            let content = voiceText
                .replacingOccurrences(of: "，", with: "<#0.1#>")
                .replacingOccurrences(of: "；", with: "<#0.2#>")
                .replacingOccurrences(of: "！", with: "<#0.2#>")
                .replacingOccurrences(of: "。", with: "<#0.2#>")
                .replacingOccurrences(of: "？", with: "<#0.2#>")
            let bean = AIVoiceChatBean(content: content, voiceId: voiceId, isSystem: isSystem)
            let result = try await AiNetManager.shared.requestAIMinMaxVoice(jsonObject: toJson(bean), modeType: AIVoiceResultBean.self)
            
            return result.data?.audio
        } else {
            return nil
        }
    }
    
    //次数是否可用
    static func isAiEnabled(_ deductAi: Double = 1) -> Bool {
        return userManager.isNoLimitAi() || getAiCount() >= deductAi
    }
    
    static func isAiVoiceEnabled(deductAi: Double = 1) -> Bool {
        return isAiEnabled(deductAi)
    }
    
    static func getAiCount() -> Double {
        return userManager.getAiCount()
    }
    
    // 如果需要实时次数变化，在当前页面直接使用
    //userManager.getAiCountStr()
    static func getAiCountStr() -> String {
        return userManager.getAiCountStr()
    }
    
    /**
     * 常规的次数扣除，默认都是1，开启记忆，则为2
     */
    static func deductAiChatCountCommon() {
        let count = AppStorageManager.shared.toggleMemoryInject ? (configManager.getConfig().aiChat.aiMemoryCount) : 1
        deductAiChatCount(Double(count))
    }
    
    /**
     * 减少ai次数
     */
    static func deductAiChatCount(_ count: Double = 1) {
        showLog("扣除点数")
        userManager.deductAiChatCount(count)
    }
    
    /**
     * 减少/增加ai次数
     */
    static func doAiChatCount(_ count: Double = 1) {
        userManager.doAiChatCount(count)
    }
    
    
    //// 输出示例：2023年10月05号 15点30分 星期四 下午
    static func getAiTime(time: TimeInterval) -> String {
        // 获取当前日期和日历实例
        let currentDate = Date(timeIntervalSince1970: time)
        let calendar = Calendar.current
        
        // 配置中文日期格式化器
        let dateFormatter = DateFormatter()
        dateFormatter.locale = Locale(identifier: "zh_CN") // 设置中文地区
        dateFormatter.dateFormat = "yyyy'年'MM'月'dd'号' HH'点'mm'分'"
        let formattedDate = dateFormatter.string(from: currentDate)
        
        // 获取时间组件
        let components = calendar.dateComponents([.hour, .weekday], from: currentDate)
        guard let hour = components.hour,
              let weekday = components.weekday else {
            return formattedDate // 获取时间失败时返回基础日期
        }
        
        // 星期几映射（注意周日是1，周六是7）
        let weekdays = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"]
        let weekdayString = weekdays[weekday - 1]
        
        // 时间段判断（使用更符合中文习惯的划分）
        let period: String = {
            switch hour {
            case 0:                 return "午夜"
            case 1...5:             return "凌晨"
            case 6...8:             return "早晨"
            case 9...11:            return "上午"
            case 12:                return "中午"
            case 13...17:           return "下午"
            case 18...19:           return "傍晚"
            case 20...23:           return "晚上"
            default:                return ""
            }
        }()
        
        // 组合最终结果
        return "\(formattedDate) \(weekdayString) \(period)"
    }
    
    static func reportError(type: String, typeName: String, message: String, errorApi: String) {
        reportErrorLocal(type: type, typeName: typeName, message: message)
        if !configManager.getConfig().getSwitchConfig().isReportAi {
            return
        }
        Task {
            do {
                let record = AiErrorRecordBean()
                record.userId = userManager.getUserId()
                record.userName = userManager.getName()
                record.channel = "apple"
                record.type = typeName
                record.message = message
                record.errorApi = errorApi
                try await LeancloudManager.instance.save(todo: record)
            } catch {
            }
        }
    }
    
    static func reportErrorLocal(type: String, typeName: String, message: String) {
        //如果是自定义，则上报自定义错误
        if (AiCustomUtils.shared.isCustomAi(type: type)) {
            if let bean = AiCustomUtils.shared.getCustomBean(type: type) {
                AiCustomUtils.shared.reportError(errorId: bean.objectId ?? "", typeName: typeName, content: message, custom: bean)
            }
        }
    }
    
    //表情包人设
    static func getEmojiPictureStr() -> String {
        // 生成并返回表情字符串
        let listKey = configManager.getConfig().emojiPicture ?? []
        let joinedKey = listKey.joined(separator: ",")
        return configManager.getConfig().getAiDescribe().emojiPictureDescribe2?.formatAiChatContent(joinedKey) ?? ""
    }
    
    
    /// 删除描述
    /// (xxx)这些的文本
    static func deleteActionDesc(_ text: String?) -> String? {
        guard let text = text else { return nil }
        
        do {
            // 匹配中英文括号及其内容（非贪婪模式）
            let regex = try NSRegularExpression(pattern: "\\([^()]*?\\)|（[^（）]*?）", options: [])
            let matches = regex.matches(in: text, options: [], range: NSRange(location: 0, length: text.count))
            
            var result = text
            // 从后往前替换，避免索引变化问题
            for match in matches.reversed() {
                let matchRange = Range(match.range, in: text)!
                let matchText = String(text[matchRange])
                
                // 检查是否是颜文字（通过特征字符判断）
                if !isKaomoji(matchText) {
                    result = result.replacingCharacters(in: matchRange, with: "")
                }
            }
            return result
        } catch {
            return text
        }
    }

    private static func isKaomoji(_ match: String) -> Bool {
        // 定义颜文字特征字符集（可根据需要扩展）
        let kaomojiChars: [Character] = [
            "^", "-", "=", "*", "+", "<", ">", "@",
            "o", "O", "x", "X", ";", "~", ".", ":",
            "'", "_", "/", "\\", "|", "\"", "♡", "・"
        ]
        
        // 检查是否包含颜文字特征字符
        if match.contains(where: { kaomojiChars.contains($0) }) {
            return true
        }
        
        // 或包含颜文字常见组合模式
        let patterns = [
            "[oO][_.-][oO]",  // 匹配 o_o, O-O, o.O 等
            "\\.\\."          // 匹配两个连续点
        ]
        
        for pattern in patterns {
            if match.range(of: pattern, options: .regularExpression) != nil {
                return true
            }
        }
        
        return false
    }
}
